package BandB.Tool.GPhoneManager.AppManager;

import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

import BandB.Tool.GPhoneManager.ConfigManager;
import BandB.Tool.GPhoneManager.MediaListener;
import BandB.Tool.GPhoneManager.R;
import BandB.Tool.GPhoneManager.AppManager.AppResore.AppRestoreManager;
import BandB.Tool.GPhoneManager.AppManager.AppResore.FileManager;
import android.app.ListActivity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Parcelable;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnCreateContextMenuListener;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;

public class UninstallerList extends ListActivity {

	private ListView list;
	private TextView loading;
	private List<ResolveInfo> mAppsInfoList;
	private List<PackageInfo> mPackageInfoList;
	private PackageManager mPackageManager;
	private NotificationManager mNotificationManager;
	private Queue<ResolveInfo> mQueueApps;
	private Queue<PackageInfo> mQueuePackages;
	private UninstallerListAppAdapter appAdapter;
	private UninstallerListAdapter allAdapter;
	private ProgressDialog mProgressDialog;
	private PackInfoItem currentAppInfo;
	private ConfigManager mConfigManager;
	private int sortMode;
	private int currentShowMode = MODE_SHOW_ACTIVITY;
	private static final byte[] SYNC = new byte[0];

	public static final String WHAT_MODE = "what_mode_to_translate";

	private static final int MODE_SORT_BY_NAME = 0;
	private static final int MODE_SORT_BY_DATE = 1;
	private static final int MODE_SORT_BY_SIZE = 2;

	private static final int MODE_SHOW_ACTIVITY = 0;
	private static final int MODE_SHOW_ALL = 1;

	private static final int MSG_START_LOADING_APPS = 0;
	private static final int MSG_START_LOADING_PACKAGES = -1;
	private static final int MSG_ADAPTER_DATA_CHANGED = 1;
	protected static final int MSG_BACKUP_FILE_COMPLETED = 2;
	protected static final int MSG_BACKUP_ONE_FILE_SUCCESS = 3;
	protected static final int MSG_BACKUP_FILE_ERROR = 7;

	private static final int MENU_ITEM_UNINSTALL_ID = 0;
	private static final int MENU_ITEM_BACKUP_ID = 1;
	private static final int MENU_ITEM_DETAILS = 2;
	private static final int MENU_ITEM_CREATE_SHORTCUT_ID = 3;
	private static final int MENU_ITEM_PIN_TO_STATUS_BAR_ID = 4;
	private static final int MENU_ITEM_LAUNCH_ID = 5;

	private static final String TAG = UninstallerList.class.getSimpleName();

	private final OnItemClickListener listItemClick = new OnItemClickListener() {
		@Override
		public void onItemClick(AdapterView<?> arg0, View arg1, int position,
				long arg3) {
			// TODO Auto-generated method stub
			if (currentShowMode == MODE_SHOW_ACTIVITY) {
				appAdapter.setCheckedAt(position);
				appAdapter.notifyDataSetChanged();
			} else {
				allAdapter.setCheckedAt(position);
				allAdapter.notifyDataSetChanged();
			}

		}
	};

	private final OnItemLongClickListener longClickListener = new OnItemLongClickListener() {
		@Override
		public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
				int position, long arg3) {
			// TODO Auto-generated method stub
			if (currentShowMode == MODE_SHOW_ACTIVITY) {
				currentAppInfo = appAdapter.getInfo(position);
			} else {
				Log.i(TAG, "current mode is show activity, ignore.");
			}
			return false;
		}
	};

	private final OnCreateContextMenuListener menuListener = new OnCreateContextMenuListener() {
		@Override
		public void onCreateContextMenu(ContextMenu menu, View v,
				ContextMenuInfo menuInfo) {
			// TODO Auto-generated method stub
			if (currentShowMode == MODE_SHOW_ACTIVITY) {
				CharSequence appName = currentAppInfo.mResolveInfo.activityInfo.applicationInfo
						.loadLabel(mPackageManager);
				menu.setHeaderTitle(appName);
				menu.add(0, MENU_ITEM_LAUNCH_ID, 5,
						R.string.MENU_ITEM_LAUNCH_TITLE);
				menu.add(0, MENU_ITEM_PIN_TO_STATUS_BAR_ID, 4,
						R.string.MENU_ITEM_PIN_TO_STATUS_BAR_TITLE);
				menu.add(0, MENU_ITEM_BACKUP_ID, 1,
						R.string.MENU_ITEM_BACKUP_TITLE);
				menu.add(0, MENU_ITEM_CREATE_SHORTCUT_ID, 6,
						R.string.MENU_ITEM_CREATE_SHORTCUT_TITLE);
				menu.add(0, MENU_ITEM_UNINSTALL_ID, 2,
						R.string.MENU_ITEM_UNINSTALL_TITLE);
				menu.add(0, MENU_ITEM_DETAILS, 3,
						R.string.MENU_ITEM_DETAILS_TITLE);
			} else {
				Log.i(TAG, "current mode is show all, so ignore long click.");
			}
		}
	};

	private final Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case MSG_BACKUP_FILE_ERROR:
				if (null != mProgressDialog) {
					mProgressDialog.dismiss();
				}
				Toast.makeText(UninstallerList.this,
						"Fail to backup. This app is removed.",
						Toast.LENGTH_SHORT).show();
				appAdapter.deleteItem(currentAppInfo);
				appAdapter.notifyDataSetChanged();
				break;
			case MSG_BACKUP_ONE_FILE_SUCCESS:
				if (null != mProgressDialog) {
					mProgressDialog.dismiss();
				}
				Toast.makeText(UninstallerList.this, "Succeed to backup.",
						Toast.LENGTH_SHORT).show();
				break;
			case MSG_BACKUP_FILE_COMPLETED:
				if (mProgressDialog != null) {
					mProgressDialog.dismiss();
				}
				Toast.makeText(UninstallerList.this, "Backup file completed.",
						Toast.LENGTH_SHORT).show();
				break;

			case MSG_ADAPTER_DATA_CHANGED:
				loading.setVisibility(View.GONE);
				if (currentShowMode == MODE_SHOW_ALL) {
					synchronized (SYNC) {
						allAdapter.addQueueData(mQueuePackages);
						allAdapter.sortByName();
						allAdapter.notifyDataSetChanged();
						SYNC.notify();
					}

				} else {
					synchronized (SYNC) {
						appAdapter.addQueueData(mQueueApps);
						appAdapter.sortByName();
						appAdapter.notifyDataSetChanged();
						SYNC.notify();
					}

				}
				break;
			case MSG_START_LOADING_PACKAGES:
				loading.setVisibility(View.VISIBLE);
				allAdapter = new UninstallerListAdapter(UninstallerList.this);
				list.setAdapter(allAdapter);
				new Thread(new Runnable() {
					@Override
					public void run() {
						// TODO Auto-generated method stub
						startLoadingPackages();
					}
				}).start();

				break;
			case MSG_START_LOADING_APPS:
				loading.setVisibility(View.VISIBLE);
				appAdapter = new UninstallerListAppAdapter(UninstallerList.this);
				list.setAdapter(appAdapter);
				new Thread(new Runnable() {
					@Override
					public void run() {
						// TODO Auto-generated method stub
						startLoadingApps();
					}
				}).start();
				break;
			default:
				break;
			}
		};
	};

	BroadcastReceiver b = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			// TODO Auto-generated method stub
			currentAppInfo = null;
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
//		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.uninstaller_list);
		initializeElements();

		currentShowMode = getIntent()
				.getIntExtra(WHAT_MODE, MODE_SHOW_ACTIVITY);
		if (currentShowMode == MODE_SHOW_ACTIVITY) {
			mHandler.sendEmptyMessage(MSG_START_LOADING_APPS);
		} else {
			mHandler.sendEmptyMessage(MSG_START_LOADING_PACKAGES);
		}
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		MenuItem item = menu.getItem(1);
		if (currentShowMode == MODE_SHOW_ACTIVITY) {
			item.setTitle(R.string.menu_show_all);
		} else if (currentShowMode == MODE_SHOW_ALL) {
			item.setTitle(R.string.menu_show_app);
		}
		switch (sortMode) {
		case MODE_SORT_BY_NAME:
			menu.findItem(R.id.sort_by_name).setChecked(true);
			menu.findItem(R.id.sort_by_date).setChecked(false);
			menu.findItem(R.id.sort_by_size).setChecked(false);
			break;
		case MODE_SORT_BY_DATE:
			menu.findItem(R.id.sort_by_name).setChecked(false);
			menu.findItem(R.id.sort_by_date).setChecked(true);
			menu.findItem(R.id.sort_by_size).setChecked(false);
			break;
		case MODE_SORT_BY_SIZE:
			menu.findItem(R.id.sort_by_name).setChecked(false);
			menu.findItem(R.id.sort_by_date).setChecked(false);
			menu.findItem(R.id.sort_by_size).setChecked(true);
			break;
		default:
			break;
		}
		return super.onPrepareOptionsMenu(menu);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		MenuInflater menuInflater = getMenuInflater();
		menuInflater.inflate(R.menu.list_menu, menu);
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		switch (item.getItemId()) {
		case R.id.menu_backup:
			if (currentShowMode == MODE_SHOW_ACTIVITY) {
				LinkedList<PackInfoItem> checkedFiles = appAdapter
						.getCheckedList();
				int size = checkedFiles.size();
				if (0 == size) {
					Toast.makeText(this, "You must select at least one file.",
							Toast.LENGTH_SHORT).show();
				} else {
					startBackupApkFiles(checkedFiles, size);
				}
			} else {
				LinkedList<PackInfoItem> checkedFiles = allAdapter
						.getCheckedList();
				int size = checkedFiles.size();
				if (0 == size) {
					Toast.makeText(this, "You must select at least one file.",
							Toast.LENGTH_SHORT).show();
				} else {
					startBackupPackageFiles(checkedFiles, size);
				}
			}
			break;
		case R.id.menu_recover:
			Intent recoverIntent = new Intent(this, AppRestoreManager.class);
			recoverIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
			startActivity(recoverIntent);
			break;
		case R.id.sort_by_date:
			sortMode = MODE_SORT_BY_DATE;
			if (currentShowMode == MODE_SHOW_ALL) {
				allAdapter.sortByDate();
				allAdapter.notifyDataSetChanged();
			} else {
				appAdapter.sortByDate();
				appAdapter.notifyDataSetChanged();
			}
			break;
		case R.id.sort_by_size:
			sortMode = MODE_SORT_BY_SIZE;
			if (currentShowMode == MODE_SHOW_ALL) {
				allAdapter.sortBySize();
				allAdapter.notifyDataSetChanged();
			} else {
				appAdapter.sortBySize();
				appAdapter.notifyDataSetChanged();
			}
			break;
		case R.id.sort_by_name:
			sortMode = MODE_SORT_BY_NAME;
			if (currentShowMode == MODE_SHOW_ALL) {
				allAdapter.sortByName();
				allAdapter.notifyDataSetChanged();
			} else {
				appAdapter.sortByName();
				appAdapter.notifyDataSetChanged();
			}
			break;
		case R.id.menu_setting:
			startActivity(new Intent(this, Settings.class));
			break;
		case R.id.show_mode:
			if (currentShowMode == MODE_SHOW_ACTIVITY) {
				currentShowMode = MODE_SHOW_ALL;
				mHandler.sendEmptyMessage(MSG_START_LOADING_PACKAGES);
			} else {
				currentShowMode = MODE_SHOW_ACTIVITY;
				mHandler.sendEmptyMessage(MSG_START_LOADING_APPS);
			}
			break;

		default:
			break;
		}

		return super.onOptionsItemSelected(item);
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		switch (item.getItemId()) {
		case MENU_ITEM_UNINSTALL_ID:
			if ((currentAppInfo.mResolveInfo.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
				uninstallApp(currentAppInfo, 0);
			} else {
				uninstallApp(currentAppInfo, 1);
			}
			break;
		case MENU_ITEM_DETAILS:
			String packageName = currentAppInfo.mResolveInfo.activityInfo.packageName;
			startApplicationDetailsActivity(packageName);
			break;
		case MENU_ITEM_CREATE_SHORTCUT_ID:
			createShortCut(currentAppInfo);
			break;
		case MENU_ITEM_PIN_TO_STATUS_BAR_ID:
			showNotification();
			break;
		case MENU_ITEM_BACKUP_ID:
			if (!MediaListener.isSDCardAvailable()) {
				Toast.makeText(this, "SD Card doesn't exist, please check it.",
						Toast.LENGTH_SHORT).show();
				break;
			}
			mProgressDialog = new ProgressDialog(this);
			mProgressDialog.setTitle("Waiting");
			mProgressDialog.setMessage("Backup...");
			mProgressDialog.show();
			new Thread(new Runnable() {
				@Override
				public void run() {
					// TODO Auto-generated method stub
					boolean backupDifferentVersion = mConfigManager
							.getDifferentVersionEnabled();
					String path = mConfigManager.getDefinedPath();
					if (FileManager.backupOneApkFile(
							currentAppInfo.mResolveInfo, mPackageManager,
							backupDifferentVersion, path)) {
						mHandler.sendEmptyMessage(MSG_BACKUP_ONE_FILE_SUCCESS);
					} else {
						Log.e(TAG, "Fail to backup package：");
						mHandler.sendEmptyMessage(MSG_BACKUP_FILE_ERROR);
					}
				}
			}).start();
			break;

		case MENU_ITEM_LAUNCH_ID:
			startApp(currentAppInfo);
			break;
		}
		return true;
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub

		if (requestCode == 1988 || requestCode == 12) {
			Log.i(TAG, "list activity returned");
			try {
				if (currentAppInfo != null) {
					mPackageManager
							.getApplicationInfo(
									currentAppInfo.mResolveInfo.activityInfo.packageName,
									0);
				}

			} catch (Exception e) {
				// TODO: handle exception
				appAdapter.deleteItem(currentAppInfo);
				appAdapter.notifyDataSetChanged();
			}
		}
		super.onActivityResult(requestCode, resultCode, data);
	}

	private void initializeElements() {
		// checkBox = (CheckBox) findViewById(R.id.app_check_box);
		// checkBox.setOnClickListener(checkClicked);
		list = getListView();
		loading = (TextView) findViewById(R.id.txtLoading);
		list.setOnItemClickListener(listItemClick);
		list.setOnItemLongClickListener(longClickListener);
		list.setOnCreateContextMenuListener(menuListener);
		list.setSaveEnabled(false);
		appAdapter = new UninstallerListAppAdapter(this);
		allAdapter = new UninstallerListAdapter(this);
		mPackageManager = getPackageManager();
		mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
		mQueueApps = new LinkedList<ResolveInfo>();
		mQueuePackages = new LinkedList<PackageInfo>();
		mConfigManager = ConfigManager.getInstance(this);
		if (mConfigManager.getPinToNotiBarEnabled()) {
			showNotificationBar();
		}
	}

	private void startLoadingApps() {
		Log.i(TAG, "loading apps...");
		sortMode = MODE_SORT_BY_NAME;
		Intent intent = new Intent(Intent.ACTION_MAIN, null);
		// intent.setAction(Intent.ACTION_MAIN);
		intent.addCategory(Intent.CATEGORY_LAUNCHER);
		mAppsInfoList = mPackageManager.queryIntentActivities(intent, 0);
		int listSize = mAppsInfoList.size();
		appAdapter.setLoadingSize(listSize);
		int count = listSize / 4;

		for (int i = 0; i < count; i++) {
			synchronized (SYNC) {
				mQueueApps.offer(mAppsInfoList.get(i * 4));
				mQueueApps.offer(mAppsInfoList.get(i * 4 + 1));
				mQueueApps.offer(mAppsInfoList.get(i * 4 + 2));
				mQueueApps.offer(mAppsInfoList.get(i * 4 + 3));

				mHandler.sendEmptyMessage(MSG_ADAPTER_DATA_CHANGED);
				try {
					SYNC.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

		}
		if (count * 4 < listSize) {
			for (int j = count * 4; j < listSize; j++) {
				mQueueApps.offer(mAppsInfoList.get(j));
			}
			mHandler.sendEmptyMessage(MSG_ADAPTER_DATA_CHANGED);
		}

	}

	private void startLoadingPackages() {
		Log.i(TAG, "loading packages...");
		sortMode = MODE_SORT_BY_NAME;
		mPackageInfoList = mPackageManager.getInstalledPackages(0);
		int listSize = mPackageInfoList.size();
		allAdapter.setLoadingSize(listSize);
		int count = listSize / 4;
		for (int i = 0; i < count; i++) {
			synchronized (SYNC) {
				mQueuePackages.offer(mPackageInfoList.get(i * 4));
				mQueuePackages.offer(mPackageInfoList.get(i * 4 + 1));
				mQueuePackages.offer(mPackageInfoList.get(i * 4 + 2));
				mQueuePackages.offer(mPackageInfoList.get(i * 4 + 3));

				mHandler.sendEmptyMessage(MSG_ADAPTER_DATA_CHANGED);
				try {
					SYNC.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

		}
		if (count * 4 < listSize) {
			for (int j = count * 4; j < listSize; j++) {
				mQueuePackages.offer(mPackageInfoList.get(j));
			}
			mHandler.sendEmptyMessage(MSG_ADAPTER_DATA_CHANGED);
		}
	}

	private void showNotificationBar() {
		Notification notification = new Notification(
				R.drawable.quick_uninstaller_icon, null, System
						.currentTimeMillis());
		Intent intent = new Intent(this, UninstallerList.class);
		intent.setAction(Intent.ACTION_SEARCH);
		PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
				intent, 0);
		notification.setLatestEventInfo(this, "App Manager",
				"Launch App Manager ListView", contentIntent);
		notification.flags = Notification.FLAG_NO_CLEAR;
		mNotificationManager.notify(Settings.NOTIFY_ID, notification);
	}

	private void showNotification() {
		try {
			Intent myIntent = new Intent(Intent.ACTION_MAIN);
			Context packageContex = createPackageContext(
					currentAppInfo.mResolveInfo.activityInfo.packageName,
					Context.CONTEXT_IGNORE_SECURITY);
			myIntent.setClassName(packageContex,
					currentAppInfo.mResolveInfo.activityInfo.name);
			int notifyId = currentAppInfo.mResolveInfo.activityInfo.packageName
					.hashCode();
			Log.i(TAG, "icon resource id ="
					+ currentAppInfo.mResolveInfo.getIconResource());
			Notification notification = new Notification(
					currentAppInfo.mResolveInfo.getIconResource(),
					"Click here to launch "
							+ currentAppInfo.mResolveInfo
									.loadLabel(mPackageManager), System
							.currentTimeMillis());
			PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
					myIntent, 0);
			notification.setLatestEventInfo(this, currentAppInfo.mResolveInfo
					.loadLabel(mPackageManager), "Launch "
					+ currentAppInfo.mResolveInfo.loadLabel(mPackageManager),
					contentIntent);
			notification.icon = notification.flags = Notification.FLAG_AUTO_CANCEL;
			mNotificationManager.notify(notifyId, notification);
		} catch (Exception e) {
			Log.e(TAG, e.getMessage());
		}
	}

	private void createShortCut(PackInfoItem info) {
		try {
			Intent myIntent = new Intent(Intent.ACTION_MAIN);
			Context packageContex = createPackageContext(
					info.mResolveInfo.activityInfo.packageName,
					Context.CONTEXT_IGNORE_SECURITY);
			myIntent.setClassName(packageContex,
					info.mResolveInfo.activityInfo.name);
			Intent intent = new Intent();
			intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
			intent.setComponent(new ComponentName("com.android.launcher",
					"com.android.launcher.InstallShortcutReceiver"));
			intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, myIntent);
			intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, info.mResolveInfo
					.loadLabel(getPackageManager()));
			Parcelable iconResource = Intent.ShortcutIconResource.fromContext(
					packageContex, info.mResolveInfo.getIconResource());
			intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource);
			sendBroadcast(intent);

			// Toast.makeText(this, "Succeed to create shortcut.",
			// Toast.LENGTH_SHORT).show();

		} catch (Exception e) {
			Log.i(TAG, "some problem occur when create shortcut");
			Toast.makeText(this,
					"Fail to create shortcut. This app is removed.",
					Toast.LENGTH_SHORT).show();
			appAdapter.deleteItem(info);
			appAdapter.notifyDataSetChanged();
		}
	}

	private void startApplicationDetailsActivity(String packageName) {
		Intent intent = new Intent(Intent.ACTION_VIEW);
		intent.setClassName("com.android.settings",
				"com.android.settings.InstalledAppDetails");
		intent.putExtra("com.android.settings.ApplicationPkgName", packageName);
		startActivityForResult(intent, 12);
	}

	private void uninstallApp(PackInfoItem information, int mode) {
		String packageName = information.mResolveInfo.activityInfo.packageName;
		Uri uri = Uri.fromParts("package", packageName, null);
		Intent uninstallPackageIntent = new Intent(Intent.ACTION_DELETE, uri);
		startActivityForResult(uninstallPackageIntent, 1988);
		Log.i(TAG, "uninstall package " + packageName);
	}

	private void startBackupApkFiles(final LinkedList<PackInfoItem> infoList,
			int size) {
		if (!MediaListener.isSDCardAvailable()) {
			Toast.makeText(this, "SD Card doesn't exist, please check it.",
					Toast.LENGTH_SHORT).show();
			return;
		}
		final int tempSize = size;
		mProgressDialog = new ProgressDialog(this);
		mProgressDialog.setTitle("Waiting");
		mProgressDialog.setMessage("Backup...");
		mProgressDialog.show();
		new Thread(new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				boolean diffVersionEnabled = mConfigManager
						.getDifferentVersionEnabled();
				String path = mConfigManager.getDefinedPath();
				for (int i = 0; i < tempSize; i++) {
					if (!FileManager.backupOneApkFile(
							infoList.get(i).mResolveInfo, mPackageManager,
							diffVersionEnabled, path)) {
						Log.e(TAG, "error occurred when backupping one file.");
					}
				}
				mHandler.sendEmptyMessage(MSG_BACKUP_FILE_COMPLETED);

			}
		}).start();
	}

	private void startBackupPackageFiles(
			final LinkedList<PackInfoItem> infoList, int size) {
		if (!MediaListener.isSDCardAvailable()) {
			Toast.makeText(this, "SD Card doesn't exist, please check it.",
					Toast.LENGTH_SHORT).show();
			return;
		}
		final int tempSize = size;
		mProgressDialog = new ProgressDialog(this);
		mProgressDialog.setTitle("Waiting");
		mProgressDialog.setMessage("Backup...");
		mProgressDialog.show();
		new Thread(new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				boolean diffVersionEnabled = mConfigManager
						.getDifferentVersionEnabled();
				String path = mConfigManager.getDefinedPath();
				for (int i = 0; i < tempSize; i++) {
					if (!FileManager.backupOneApkFile(
							infoList.get(i).mPackageInfo, mPackageManager,
							diffVersionEnabled, path)) {
						Log.e(TAG, "error occurred when backupping one file.");
					}
				}
				mHandler.sendEmptyMessage(MSG_BACKUP_FILE_COMPLETED);

			}
		}).start();
	}

	private void startApp(PackInfoItem information) {
		try {
			Intent myIntent = new Intent(Intent.ACTION_MAIN);
			Context packageContex = createPackageContext(
					information.mResolveInfo.activityInfo.packageName,
					Context.CONTEXT_IGNORE_SECURITY);

			myIntent.setClassName(packageContex,
					information.mResolveInfo.activityInfo.name);
			startActivity(myIntent);
		} catch (Exception e) {
			Log.i(TAG, "can't start application" + e.getMessage());
			Toast.makeText(this,
					"Fail to create shortcut. This app is removed.",
					Toast.LENGTH_SHORT).show();
			appAdapter.deleteItem(information);
			appAdapter.notifyDataSetChanged();
		}
	}
}
